module Proxy.Messages where
import Proxy.Game
import Proxy.TechTypes
import Proxy.UpgradeTypes
import Proxy.UnitTypes
import Proxy.CommandTypes
import qualified Proxy.Orders as Orders

type Ack = [Player]

type StartingLocations = [Location]

data MapData = MapData Name Width Height [Tile] deriving Show

type ChokeData = [Choke]

type BaseData = [Location]

data TimeData = TimeData { buildTime    :: Time
                         , trainTime    :: Time
                         , researchTime :: Time
                         , upgradeTime  :: Time 
                         , orderTimer   :: OrderTimer
                         } deriving Show

data UnitData = UnitData { unitId        :: UnitId
                         , unitOwnerId   :: PlayerId
                         , unitType      :: UnitType
                         , unitLocation  :: Location
                         , unitHealth    :: Health
                         , unitShields   :: Shields
                         , unitEnergy    :: Energy
                         , unitTimeData  :: TimeData
                         , unitOrder     :: Orders.Order
                         , unitResources :: Int
                         , unitAddonId   :: AddonId
                         , unitMineCount :: MineCount
                         } deriving Show

data GameState = GameState { gameResources     :: Resources
                           , gameSupply        :: Supply
                           , gameTechStatus    :: [(TechType, TechStatus)]
                           , gameUpgradeStatus :: [(UpgradeType, UpgradeStatus)]
                           , gameUnits         :: [UnitData]
                           } deriving Show

data GameInfo = GameInfo { gamePlayers           :: [Player]
                         , gameStartingLocations :: [Location]
                         , gameMap               :: MapData
                         , gameTerrain           :: (Maybe (ChokeData, BaseData))
                         } deriving Show

data Options = Options [Bool] deriving Show

instance Serialize Bool where
    serializes = shows . fromEnum

instance Serialize Options where
    serializes (Options bools) = serializesBools bools where
        serializesBools = foldr ((.) . serializes) (""++)

type CommandArgs = String

data Command = Command CommandType CommandArgs deriving (Show, Eq)

class Serialize a where
    serializes :: a -> ShowS
    serialize  :: a -> String
    serialize x = serializes x ""

instance Serialize CommandType where
    serializes = shows . fromEnum

instance Serialize UnitType where
    serializes = shows . fromEnum

instance Serialize UpgradeType where
    serializes = shows . fromEnum

instance Serialize Int where
    serializes = shows

instance Serialize TechType where
    serializes = shows . fromEnum

instance Serialize Command where
    serializes (Command t args) = serializes t . (';':) . (args ++)

data Commands = Commands [Command]

instance Serialize Commands where
    serializes (Commands []) = ("" ++)
    serializes (Commands cs) = ("commands" ++) . serializesCommands cs where
        serializesCommands [] = (""++)
        serializesCommands (c:cs) = (':' :) . serializes c . serializesCommands cs


